(function(){
   window.Run =  {};

	var Transform=(function(){ //兼容 transform
	    var json = {
	    transform:'transform',
	    webkitTransform:'webkitTransform',
	    MozTransform:'MozTransform',
	    msTransform:'msTransform',
	    OTransform:'OTransform'
	    };
	    for(var name in json){if(typeof document.body.style[name] === "string"){return json[name];}}
	})();

   function elementMove(obj,options){ // 处理运动
   		var self = this;
	   	 if (typeof(obj) == 'string') {
	        obj = document.querySelector(obj);   
	     }
	    
	     //设置默认选项
	     options = options || {};
	     options.easing = options.easing ||  Run.Tween.Quad.easeInOut;
	     options.time = options.time || 1000; 
       options.onEnd = options.onEnd || null ; 
	     options.onUpdate = options.onUpdate || null ; 

	    this.isRotationZ=true;
	    this.start = 0;
	    this.dis = 0;

	    this.getRotateZ = function(obj){//获取 rotateZ 值
	    	 var s = obj.style[Transform];
		     if(s.indexOf('rotateZ') > -1 ){ //有 rotateZ 属性
		         return parseFloat(s.split('(')[1]) ;
		     }else{
		        return 0;
		     }
	    };

	    this.getPositionY = function(obj){//获取 backgroundPositionY 值
	    	 var s = obj.style['backgroundPositionY'];
		     if(s){ 
		         return parseFloat(s) ;
		     }else{
		        return 0;
		     }
	    };

	    if(options["rotationZ"]){
	        self.start = self.getRotateZ(obj);
	        self.dis = options["rotationZ"] - self.start;
	    }else if(options["backgroundPositionY"]){
	    	self.start = self.getPositionY(obj);
	        self.dis = options["backgroundPositionY"] - self.start;
	        self.isRotationZ = false;
	    }else{
         throw "Run只支持 rotationZ 和 backgroundPositionY, can't Run!!!";
	    }

	    var count = Math.round(options.time * 1000 /10); //次数
	    var n = 0;
	    clearInterval(obj.timer);
	    obj.timer = setInterval(function(){
	      n++;
	      var cur = options.easing(n/count*options.time,self.start,self.dis,options.time);
	      if(self.isRotationZ){
	      	 obj.style[Transform] = 'rotateZ(' + cur  + 'deg) ';
	      }else{
	      	 obj.style['backgroundPositionY'] = cur + 'px';
	      }
        options.onUpdate &&  options.onUpdate(cur);
	      if(n==count){
	        clearInterval(obj.timer);
	        options.onEnd &&  options.onEnd();
	      }

	    },10);

	    this.stop = function(target){
	    	var aDom =  document.querySelectorAll(target);
	    	for(var i =0;i<aDom.length;i++){
	    		clearInterval(aDom[i].timer);
	    		options.onEnd &&  options.onEnd();
	    	}
	    };

  } //处理运动 end

   //---- 暴露3个方法
   Run.setRotateZ = function(obj,z){
  	 document.querySelector(obj).style[Transform] = 'rotateZ(' + z  + 'deg) ';
   };

   Run.to = function(obj,options){
  	  Run.Run = new elementMove(obj,options);
   };

   Run.stop = function(target){
   		if(Run.Run){
   			Run.Run.stop(target);
   		}
   };

   // 处理缓冲
   Run.Tween = {
        Linear: function(t,b,c,d){ 
        	return c*t/d + b; 
        },
        Quad: {
           easeIn: function(t,b,c,d){
               return c*(t/=d)*t + b;
           },
           easeOut: function(t,b,c,d){
               return -c *(t/=d)*(t-2) + b;
           },
           easeInOut: function(t,b,c,d){
               if ((t/=d/2) < 1) return c/2*t*t + b;
               return -c/2 * ((--t)*(t-2) - 1) + b;
           }
        },
        Cubic: {
           easeIn: function(t,b,c,d){
               return c*(t/=d)*t*t + b;
           },
           easeOut: function(t,b,c,d){
               return c*((t=t/d-1)*t*t + 1) + b;
           },
           easeInOut: function(t,b,c,d){
               if ((t/=d/2) < 1) return c/2*t*t*t + b;
               return c/2*((t-=2)*t*t + 2) + b;
           }
        },
        Quart: {
           easeIn: function(t,b,c,d){
               return c*(t/=d)*t*t*t + b;
           },
           easeOut: function(t,b,c,d){
               return -c * ((t=t/d-1)*t*t*t - 1) + b;
           },
           easeInOut: function(t,b,c,d){
               if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
               return -c/2 * ((t-=2)*t*t*t - 2) + b;
           }
        },
        Quint: {
           easeIn: function(t,b,c,d){
               return c*(t/=d)*t*t*t*t + b;
           },
           easeOut: function(t,b,c,d){
               return c*((t=t/d-1)*t*t*t*t + 1) + b;
           },
           easeInOut: function(t,b,c,d){
               if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
               return c/2*((t-=2)*t*t*t*t + 2) + b;
           }
        },
        Sine: {
           easeIn: function(t,b,c,d){
               return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
           },
           easeOut: function(t,b,c,d){
               return c * Math.sin(t/d * (Math.PI/2)) + b;
           },
           easeInOut: function(t,b,c,d){
               return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
           }
        },
        Expo: {
           easeIn: function(t,b,c,d){
               return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
           },
           easeOut: function(t,b,c,d){
               return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
           },
           easeInOut: function(t,b,c,d){
               if (t==0) return b;
               if (t==d) return b+c;
               if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
               return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
           }
        },
        Circ: {
           easeIn: function(t,b,c,d){
               return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
           },
           easeOut: function(t,b,c,d){
               return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
           },
           easeInOut: function(t,b,c,d){
               if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
               return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
           }
        }

      };

 })();

